﻿

var net = require("net");

var parser = require("./MyRequest");
var router = require("./router");
var settings = require("./settings");

var events = require('events');
var channel = new events.EventEmitter();
var resourceHandler = require("./resourceHandler");


var myHttpServer = function (opts) {

    // this.port = opts.port;
    // this.resourceMapRootFolder = opts.resourceMapRootFolder;
    // this.rootFolder = opts.rootFolder;

    this.myStatus = {

        isStarted: false,
        startedDate: null,
        port: 0,
        resourceMap: {},
        resourceMapRootFolder: "",
        rootFolder: "",
        numOfCurrentRequests: 0,
        addToAllCounter: function () {
            this.numOfCurrentRequests += 1;
            this.precentageOfStaticRequests = (this.numOfStaticRequests / this.numOfCurrentRequests) * 100;
            this.precntageOfSuccesfulRequests = (this.numOfSuccesfulRequests / this.numOfCurrentRequests) * 100;

        },
        numOfStaticRequests: 0,

        addStaticCounter: function () {
            this.numOfStaticRequests += 1;
            this.precentageOfStaticRequests = (this.numOfStaticRequests / this.numOfCurrentRequests) * 100;
        },

        precentageOfStaticRequests: 0,
        numOfSuccesfulRequests: 0,

        addSuccesfulCounter: function () {
            this.numOfSuccesfulRequests += 1;
            this.precntageOfSuccesfulRequests = (this.numOfSuccesfulRequests / this.numOfCurrentRequests) * 100;
        },

        precntageOfSuccesfulRequests: 0
    };


    this.allSessions = {};

    this.sessionExperation = {};

    this.apContext = {};

    this.server = null;
};


myHttpServer.prototype = new events.EventEmitter;
module.exports = myHttpServer;






myHttpServer.prototype.createServer = function (port, resourceMapRootFolder, rootFolder) {


    this.myStatus.port = port;
    this.myStatus.resourceMapRootFolder = resourceMapRootFolder;
    this.myStatus.rootFolder = rootFolder;

    //lockStartServer.v();


    this.filesDone = false;
    this.isListening = false;
    var self = this;
    resourceHandler.getResourceMap(resourceMapRootFolder, this.myStatus.resourceMap, function () {

        //console.log("resourceMap is ready for you");
        //lockStartServer.p();



        if (self.myStatus.resourceMap["/init"] !== undefined) {


            var dummy = "GET /dummy HTTP/1.0 \r\n\r\n";

            var myRequest = parser.getRequestObj(dummy.toString('utf8', 0, dummy.length), self.allSessions, self.apContext, self.sessionExperation);
            var myResponse = parser.getResponseObj();
            myResponse.end = function () {
                self.filesDone = true;

                if (self.isListening === true && self.filesDone === true) {
                    //    console.log(" >>>>> emiiting start from initCB in end() <<< ");
                    self.emit('start');
                }
            };

            self.myStatus.resourceMap["/init"](myRequest, myResponse);

        } else {
            self.filesDone = true;

            if (self.isListening === true && self.filesDone === true) {
                // console.log(" >>>>> emiiting start from jssCB <<< ");
                self.emit('start');
            }
        }




    });

}







myHttpServer.prototype.start = function () {


    this.myStatus.isStarted = true;
    this.myStatus.startedDate = new Date();

    this.myStatus.numOfCurrentRequests = 0;
    this.myStatus.precentageOfStaticRequests = 0;
    this.myStatus.precntageOfSuccesfulRequests = 0;

    var self = this;


    function onRequest(socket) {


        function socketEnd() {

            //console.log("haha closing you sucker!!ssocket=" + socket);
            //TODO get this back!!
            socket.end();



        }
        //console.log("new socket>>>>>>>");

        var buffer = "";
        var bodyCnt = 0;
        var multipart = false;

        var timeout = setTimeout(socketEnd, settings.LAST_REQUEST_TIMEOUT_SEC * 1000);
        socket.on('data', function (dat) {

            //console.log("new socket>>>>>>>");
            buffer += dat.toString('utf8', 0, dat.length);

            clearTimeout(timeout);
            timeout = setTimeout(socketEnd, settings.LAST_REQUEST_TIMEOUT_SEC * 1000);

            var myResponse = parser.getResponseObj(socket);

            try {

                var myRequest = parser.getRequestObj(buffer, self.allSessions, self.apContext, self.sessionExperation);

                var length = myRequest.headers["Content-Length"];
                if (length && length > myRequest.body.length) {

                    return;

                } else {
                    buffer = "";
                }

                myResponse.uid = myRequest.uid;
                myResponse.httpVersion = myRequest.httpVersion;
                myResponse.headers['Connection'] = myRequest.headers['Connection'];

                myResponse.doForward = function () {

                    if (myResponse.forwardTo === undefined) {
                        return;

                    } else {

                        var resource = myResponse.forwardTo["resource"];

                        var req = myResponse.forwardTo["request"];
                        var res = myResponse.forwardTo["response"];
                        myResponse.forwardTo = undefined;

                        //router.routeForward(self.myStatus.resourceMap, resource, res, req);
                        router.route(self.myStatus.resourceMap, resource, res, req, self.myStatus.rootFolder, self.myStatus);




                    }



                }

                var cookie = {
                    key: settings.SESSION_COOKIE_KEY,
                    value: myResponse.uid,
                    path: "/",
                    domain: undefined,
                    expire: self.sessionExperation[myRequest.uid],
                    httpOnly: false
                };


                myResponse.addCookie(cookie);


                // console.log("http ver:" + myResponse.httpVersion + " conn:" + myResponse.headers['Connection']);


                var pathname = myRequest.resource;

                self.myStatus.addToAllCounter();



                router.route(self.myStatus.resourceMap, pathname, myResponse, myRequest, self.myStatus.rootFolder, self.myStatus);





            } catch (err) {

                var pattern = /^\d{3}$/; //check if err is a status code
                myResponse.status = (pattern.test(err)) ? err : 500;

                myResponse.headers['Connection'] = 'close';

                myResponse.end();

            }

        });


        socket.on('end', function (dat) {
            clearTimeout(timeout);
            //console.log("bye bye");
        });




    }

    //console.log("start() was called!!");


    // lockStartServer.v();

    this.server = net.createServer(onRequest);


    this.server.on('listening', function () {
        // console.log("Server has stated to listen :-) ");
        //lockStartServer.p();
        self.isListening = true;

        if (self.isListening === true && self.filesDone === true) {
            //  console.log(" <<<< emiiting start from StartServer listening CB >>>> ");
            self.emit('start');
        }


    });

    this.server.on('close', function () {

        // isListening = false;
        //  console.log("Server has closed down :-( ");
        //console.log(" *** stop emitted *** ");
        self.emit('stop');

    });






    this.server.listen(this.myStatus.port, "127.0.0.1");





}


myHttpServer.prototype.stop = function () {

    this.server.close();
    this.myStatus.isStarted = false;

   

}


myHttpServer.prototype.status = function () {

    return this.myStatus;
}




